switchroot: Refactor /boot mounting into helper function
authorColin Walters <walters@verbum.org>
Tue, 22 Jul 2025 20:41:49 +0000 (16:41 -0400)
committerColin Walters <walters@verbum.org>
Thu, 24 Jul 2025 14:26:09 +0000 (10:26 -0400)
So it can be shared with soft reboots.

Signed-off-by: Colin Walters <walters@verbum.org>
src/libotcore/otcore-prepare-root.c
src/libotcore/otcore.h
src/switchroot/ostree-prepare-root.c

index fba052706b381c9d55ecc16a6b0888374850c42a..c8bbf6bf02b0cbe35c77187bf63b1dd599c49c33 100644 (file)
@@ -383,6 +383,35 @@ composefs_error_message (int errsv)
 
 #endif
 
+/**
+ * otcore_mount_boot:
+ *
+ * Mount /boot as a bind mount for a deployment if it's on the same partition
+ * as the physical root.
+ */
+gboolean
+otcore_mount_boot (const char *physical_root, const char *deployment, GError **error)
+{
+  g_autofree char *boot_loader = g_build_filename (physical_root, "boot/loader", NULL);
+  struct stat stbuf;
+
+  /* If /boot is on the same partition, use a bind mount to make it visible
+   * at /boot inside the deployment.
+   */
+  if (!(lstat (boot_loader, &stbuf) == 0 && S_ISLNK (stbuf.st_mode)))
+    return TRUE;
+
+  g_autofree char *target_boot = g_build_filename (deployment, "boot", NULL);
+  if (!(lstat (target_boot, &stbuf) == 0 && S_ISDIR (stbuf.st_mode)))
+    return TRUE;
+
+  g_autofree char *src_boot = g_build_filename (physical_root, "boot", NULL);
+  if (mount (src_boot, target_boot, NULL, MS_BIND | MS_SILENT, NULL) < 0)
+    return glnx_throw (error, "failed to bind mount /boot");
+
+  return TRUE;
+}
+
 /**
  * otcore_mount_etc:
  *
index 0c7329d326b0265008b5003e0e0ffee7140045ae..212eafe871350c390427bb92ac1f9dc1dd1be6f6 100644 (file)
@@ -99,6 +99,7 @@ RootConfig *otcore_load_rootfs_config (const char *cmdline, GKeyFile *config, gb
 gboolean otcore_mount_rootfs (RootConfig *rootfs_config, GVariantBuilder *metadata_builder,
                               const char *root_mountpoint, const char *deploy_path,
                               const char *mount_target, bool *out_using_composefs, GError **error);
+gboolean otcore_mount_boot (const char *physical_root, const char *deploy_path, GError **error);
 
 gboolean otcore_mount_etc (GKeyFile *config, GVariantBuilder *metadata_builder,
                            const char *mount_target, GError **error);
index c7df55d0f860f370e1942c107ec0f294872973f1..7743eff0163f7ae6d4166e1da53159da23338437 100644 (file)
@@ -280,21 +280,8 @@ main (int argc, char *argv[])
   g_variant_builder_add (&metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_SYSROOT_RO,
                          g_variant_new_boolean (sysroot_readonly));
 
-  /* Prepare /boot.
-   * If /boot is on the same partition, use a bind mount to make it visible
-   * at /boot inside the deployment. */
-  if (snprintf (srcpath, sizeof (srcpath), "%s/boot/loader", root_mountpoint) < 0)
-    err (EXIT_FAILURE, "failed to assemble /boot/loader path");
-  if (lstat (srcpath, &stbuf) == 0 && S_ISLNK (stbuf.st_mode))
-    {
-      if (lstat ("boot", &stbuf) == 0 && S_ISDIR (stbuf.st_mode))
-        {
-          if (snprintf (srcpath, sizeof (srcpath), "%s/boot", root_mountpoint) < 0)
-            err (EXIT_FAILURE, "failed to assemble /boot path");
-          if (mount (srcpath, TMP_SYSROOT "/boot", NULL, MS_BIND | MS_SILENT, NULL) < 0)
-            err (EXIT_FAILURE, "failed to bind mount %s to boot", srcpath);
-        }
-    }
+  if (!otcore_mount_boot (root_mountpoint, TMP_SYSROOT, &error))
+    errx (EXIT_FAILURE, "%s", error->message);
 
   /* Prepare /etc.
    * No action required if sysroot is writable. Otherwise, a bind-mount for